package com.heima.service.impl;


import com.heima.component.RedisComponent;
import com.heima.entity.config.AppConfig;
import com.heima.entity.constants.Constants;
import com.heima.entity.dto.SessionWebUserDto;
import com.heima.entity.dto.SysSettingsDto;
import com.heima.entity.dto.UserSpaceDto;
import com.heima.entity.enums.PageSize;
import com.heima.entity.enums.ResponseCodeEnum;
import com.heima.entity.enums.UserStatusEnum;
import com.heima.entity.po.EmailCode;
import com.heima.entity.po.FileInfo;
import com.heima.entity.po.UserInfo;
import com.heima.entity.query.EmailCodeQuery;
import com.heima.entity.query.FileInfoQuery;
import com.heima.entity.query.SimplePage;
import com.heima.entity.query.UserInfoQuery;
import com.heima.entity.vo.PaginationResultVO;
import com.heima.exception.BusinessException;
import com.heima.mapper.EmailCodeMapper;
import com.heima.mapper.FileInfoMapper;
import com.heima.mapper.UserInfoMapper;
import com.heima.service.EmailCodeService;
import com.heima.service.FileInfoService;
import com.heima.service.UserInfoService;
import com.heima.utils.StringTools;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;


/**
 * 用户信息 业务接口实现
 */
@Service("userInfoService")
public class UserInfoServiceImpl implements UserInfoService {

    @Resource
    private UserInfoMapper<UserInfo, UserInfoQuery> userInfoMapper;

    @Resource
    private RedisComponent redisComponent;
    @Resource
    private EmailCodeService emailCodeService;

    @Resource
    private AppConfig appConfig;
    @Resource
    private FileInfoService fileInfoService;
    @Resource
    private EmailCodeMapper<EmailCode, EmailCodeQuery> emailCodeMapper;
    @Resource
    private FileInfoMapper<FileInfo, FileInfoQuery> fileInfoMapper;

    @Override
    public List<UserInfo> findListByParam(UserInfoQuery param) {
        return this.userInfoMapper.selectList(param);
    }

    @Override
    public Integer findCountByParam(UserInfoQuery param) {
        return this.userInfoMapper.selectCount(param);
    }

    @Override
    public PaginationResultVO<UserInfo> findListByPage(UserInfoQuery param) {
        int count = this.findCountByParam(param);
        int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

        SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
        param.setSimplePage(page);
        List<UserInfo> list = this.findListByParam(param);
        PaginationResultVO<UserInfo> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(String email, String password, String nickName, String emailCode) {

        UserInfo userInfo = (UserInfo) userInfoMapper.selectByEmail(email);
        if(userInfo!=null){
            throw new BusinessException("邮箱账号已经存在");
        }
        UserInfo NickNameUser = (UserInfo) userInfoMapper.selectByNickName(nickName);
        if(NickNameUser!=null){
            throw new BusinessException("昵称已经存在");
        }

        //校验邮箱验证码
        emailCodeService.verifyEmailCode(email,emailCode);

        String userId = StringTools.getRandomNumber(Constants.LENGTH_10);

        UserInfo user = new UserInfo();
        user.setEmail(email);
        user.setNickName(nickName);
        user.setUserId(userId);
        user.setPassword(StringTools.encodeByMD5(password));
        user.setJoinTime(new Date());
        user.setStatus(UserStatusEnum.ENABLE.getStatus());
        user.setUseSpace(0L);
        SysSettingsDto sysSettingsDto = redisComponent.getsysSettingsDto();
        user.setTotalSpace(sysSettingsDto.getUserInitUseSpace()*Constants.MB);
        try {
            userInfoMapper.insert(user);
        }catch (DataIntegrityViolationException e){
            throw new BusinessException("昵称已存在");
        }

    }

    @Override
    public SessionWebUserDto login(String email, String password) {
        UserInfo userInfo = (UserInfo) userInfoMapper.selectByEmail(email);
        if (userInfo == null|| !password.equals(userInfo.getPassword())){
            throw new BusinessException("账号或密码错误");
        }
        if (userInfo.getStatus() == 0){
            throw new BusinessException("账号已停用");
        }
        userInfo.setLastLoginTime(new Date());

        userInfoMapper.updateByUserId(userInfo,userInfo.getUserId());
        SessionWebUserDto sessionWebUserDto = new SessionWebUserDto();
        sessionWebUserDto.setUserId(userInfo.getUserId());
        sessionWebUserDto.setNickName(userInfo.getNickName());
        //多个管理员账号用逗号隔开
        if (ArrayUtils.contains(appConfig.getAdminEmails().split(","), email)) {
            sessionWebUserDto.setAdmin(true);
        } else {
            sessionWebUserDto.setAdmin(false);
        }

        UserSpaceDto userSpaceDto = new UserSpaceDto();
        Long l = fileInfoMapper.selectUseSpace(userInfo.getUserId());
        userSpaceDto.setUseSpace(l);
        userSpaceDto.setTotalSpace(userInfo.getTotalSpace());
        redisComponent.saveUserSpace(userInfo.getUserId(),userSpaceDto);
        return sessionWebUserDto;


    }

    @Override
    public void resetPwd(String email, String password, String emailCode) {
        UserInfo userInfo = userInfoMapper.selectByEmail(email);
        emailCodeService.verifyEmailCode(email,emailCode);

        userInfo.setPassword(StringTools.encodeByMD5(password));
        userInfoMapper.updateByUserId(userInfo, userInfo.getUserId());


    }

    @Override
    public void updateUserInfoByUserId(UserInfo userInfo, String userId) {
        Integer i = userInfoMapper.updateByUserId(userInfo, userId);
        if (i == null){
            throw new BusinessException("用户不存在");
        }
    }

    @Override
    public void updatePassword(String password, HttpSession session) {
        SessionWebUserDto attribute = (SessionWebUserDto) session.getAttribute(Constants.SESSION_KEY);
        if(attribute == null){
            throw new BusinessException("服务出现错误，请联系客服");
        }
        String userId = attribute.getUserId();
        UserInfo userInfo = new UserInfo();
        userInfo.setPassword(StringTools.encodeByMD5(password));
        userInfoMapper.updateByUserId(userInfo,userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserStatus(String userId, Integer status) {
        UserInfo userInfo = new UserInfo();
        userInfo.setStatus(status);
        if (UserStatusEnum.DISABLE.getStatus() == status){
            userInfo.setUseSpace(0L);
            fileInfoMapper.deleteFileByUserId(userId);
        }
        userInfoMapper.updateByUserId(userInfo,userId);
    }

    @Override
    public void updateUserSpace(String userId, Long changeSpace) {
        if (changeSpace < 0){
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        UserSpaceDto userSpaceUse = redisComponent.getUserSpaceUse(userId);
        userSpaceUse.setTotalSpace(changeSpace);
        redisComponent.saveUserSpace(userId,userSpaceUse);

        userInfoMapper.updateUserTrulySpace(userId,userSpaceUse.getUseSpace(),userSpaceUse.getTotalSpace());
    }

    @Override
    public PaginationResultVO<FileInfo> loadFileList(FileInfoQuery fileInfoQuery) {
        PaginationResultVO<FileInfo> listByPage = fileInfoService.findListByPage(fileInfoQuery);
        return listByPage;
    }

    @Override
    public UserInfo getUserInfoByUserId(String userId) {
        UserInfo userInfo = userInfoMapper.selectByUserId(userId);
        return userInfo;
    }
}